
/** 
 * @file		ENC28J60.c
 * @brief				
 * @details	Project	: BHS-Ethernet 
 * 
 * 
 * @author	Seven Zeng
 * @date		1/12/2019
 * @copyright	MICC Tech All rights reserved
 * 
 ************************************************************** 
 * @par
 * 
 * 
 ************************************************************** 
 */
 
 
//===============================INCLUDE==========================

#define ENC28J60_DEF
#include "ENC28J60.h"
#include "SPI.h"
//================================================================





//=========================TYPE DEFINITIONS=======================


//================================================================




//=========================CONST DEFINITIONS======================
enum {
	ENC_CMD_READ_CTRL_REG = 0X00,
	ENC_CMD_READ_BUFFER = 0X3A,
	ENC_CMD_WRITE_CTRL_REG = 0X40,
	ENC_CMD_WRITE_BUFFER = 0X7A,
	ENC_CMD_BIT_SET = 0X80,
	ENC_CMD_BIT_RESET = 0XA0,
	ENC_CMD_RESET = 0XE0
};




//================================================================




//=========================VARIABLE DECLARATIONS==================

static T_SPI_INFO ethernetSPI;



//================================================================




//=========================ROUTINE PROTOTYPES=====================

/**
 * @param
 * @param
 * @param
 */
static void CommonWrite(u8 opCode, u8 address, u8 value)
{
	u8 buffer[2];
	buffer[0] = opCode | (address & 0x1F);
	buffer[1] = value;

	SPI_ReadWriteBlock (&ethernetSPI, buffer, buffer, 2);
}


void ENC28J60_Init (void)
{
	
	SPI_Init (&ethernetSPI, SPI1, 500000, 0);

}

u8 ENC28J60_ReadEthControlRegister(u8 address)
{
	u8 buffer[2];
	buffer[0] = ENC_CMD_READ_CTRL_REG | (address & 0x1F);
	buffer[1] = 0x00;

	SPI_ReadWriteBlock (&ethernetSPI, buffer, buffer, 2);

	return buffer[1];
}

u8 ENC28J60_ReadMACOrMIIControlRegister(u8 address)
{
	u8 buffer[3];
	buffer[0] = ENC_CMD_READ_CTRL_REG | (address & 0x1F);
	buffer[1] = 0x00;
	buffer[2] = 0x00;

	SPI_ReadWriteBlock (&ethernetSPI, buffer, buffer, 3);

	return buffer[2];
}

void ENC28J60_WriteControlRegister (u8 address, u8 value)
{
	CommonWrite (ENC_CMD_WRITE_CTRL_REG, address, value);
}


void ENC28J60_ReadBuffer(/*u8 startAddrLo, u8 startAddrHi, */u8* pDest, u16 count)
{
//	// Set read point first	
//	CommonWrite (ENC_CMD_WRITE_CTRL_REG, BANK0_ERDPTL, startAddrLo);
//	CommonWrite (ENC_CMD_WRITE_CTRL_REG, BANK0_ERDPTH, startAddrHi);


	SPI_Select ();

	SPI_ReadWriteByte_WithoutSelect(&ethernetSPI, ENC_CMD_READ_BUFFER);

	SPI_ReadWriteBlock_WithoutSelect (&ethernetSPI, pDest, pDest, count);

	SPI_Deselect ();
}

void ENC28J60_WriteBuffer(u16 startAddr, u8* pSrc, u16 count)
{
	SPI_Select ();

	SPI_ReadWriteByte_WithoutSelect(&ethernetSPI, ENC_CMD_WRITE_BUFFER);

	SPI_ReadWriteBlock_WithoutSelect (&ethernetSPI, pSrc, pSrc, count);

	SPI_Deselect ();

}


void ENC28J60_SetEthBits(u8 address, u8 bitMask)
{
	CommonWrite (ENC_CMD_BIT_SET, address, bitMask);
}

void ENC28J60_ResetEthBits(u8 address, u8 bitMask)
{
	CommonWrite (ENC_CMD_BIT_RESET, address, bitMask);
}


void ENC28J60_SetBank(u8 bank)
{	
	CommonWrite (ENC_CMD_BIT_RESET, BANK0_ECON1, 0x03);
	CommonWrite (ENC_CMD_BIT_SET, BANK0_ECON1, bank & 0x03);
}

void ENC28J60_Reset(void)
{
	SPI_ReadWriteByte (&ethernetSPI, ENC_CMD_RESET);
}


u16 ENC28J60_ReadPHYRegister(u8 PHYaddr) 
{
	u16 PHYreg;

	ENC28J60_SetBank(0x02);
	// Setup phy register address
	CommonWrite(ENC_CMD_WRITE_CTRL_REG, BANK2_MIREGADR, PHYaddr);
	// issue read command
	CommonWrite(ENC_CMD_WRITE_CTRL_REG, BANK2_MICMD, 0x01);
	// wait until read finished	
	ENC28J60_SetBank(0x03);
	while ((ENC28J60_ReadMACOrMIIControlRegister(BANK3_MISTAT) & 0x01) == 0x01);

	ENC28J60_SetBank(0x02);
	PHYreg = (u16)ENC28J60_ReadMACOrMIIControlRegister(BANK2_MIRDH) << 8;
	PHYreg |= ENC28J60_ReadMACOrMIIControlRegister(BANK2_MIRDL);

	return PHYreg;

}

void ENC28J60_WritePHYRegister(u8 PHYaddr, u16 value)
{
	ENC28J60_SetBank(0x02);
	// Setup phy register address
	CommonWrite(ENC_CMD_WRITE_CTRL_REG, BANK2_MIREGADR, PHYaddr);
	// Write phy reg value to mii register, the writting will be started
	// automatically after MIWRH is written
	// Notic that the written to PHY will be finished after 10.24us rather
	// than immediately
	CommonWrite(ENC_CMD_WRITE_CTRL_REG, BANK2_MIWRL, value & 0xFF);
	CommonWrite(ENC_CMD_WRITE_CTRL_REG, BANK2_MIWRH, value >> 8);

}

//================================================================




